import {
	SerializedError,
	createAsyncThunk,
	createSlice,
} from '@reduxjs/toolkit'
import { RootState, TProductData } from '../../types'
import api from '../../../api'
import {
	TProductRequest,
	TProductResponse,
	TProductReviewRequest,
	TProductReviewResponse,
} from '../../../api/api'

type TProductState = {
	data: TProductData | null
	loading: boolean
	error: SerializedError | null | unknown
}

const initialState: TProductState = {
	data: null,
	loading: false,
	error: null,
}

const sliceName = 'product'

export const fetchProduct = createAsyncThunk<TProductResponse, TProductRequest>(
	`${sliceName}/fetchProduct`,
	async (params, { getState }) => {
		try {
			const response = await api(
				(getState() as RootState).user.token
			).getProduct(params)
			return response
		} catch (error) {
			return error
		}
	}
)

export const fetchDeleteProduct = createAsyncThunk<
	TProductResponse,
	TProductRequest
>(`${sliceName}/fetchDeleteProduct`, async (params, { getState }) => {
	try {
		const response = await api(
			(getState() as RootState).user.token
		).deleteProduct(params)
		return response
	} catch (error) {
		return error
	}
})

export const fetchSetLike = createAsyncThunk<TProductResponse, TProductRequest>(
	`${sliceName}/fetchSetLike`,
	async (params, { getState }) => {
		try {
			const response = await api((getState() as RootState).user.token).setLike(
				params
			)
			return response
		} catch (error) {
			return error
		}
	}
)

export const fetchSetDislike = createAsyncThunk<
	TProductResponse,
	TProductRequest
>(`${sliceName}/fetchSetDislike`, async (params, { getState }) => {
	try {
		const response = await api((getState() as RootState).user.token).setDislike(
			params
		)
		return response
	} catch (error) {
		return error
	}
})

export const fetchAddReview = createAsyncThunk<
	TProductReviewResponse,
	TProductReviewRequest
>(`${sliceName}/fetchAddReview`, async (params, { getState }) => {
	try {
		const response = await api(
			(getState() as RootState).user.token
		).addProductReview(params)
		return response
	} catch (error) {
		return error
	}
})

export const productSlice = createSlice({
	name: sliceName,
	initialState,
	reducers: {},
	extraReducers: (builder) => {
		builder
			.addCase(fetchProduct.fulfilled, (state, action) => {
				state.data = action.payload
				state.loading = false
			})
			.addCase(fetchProduct.pending, (state) => {
				state.loading = true
				state.error = null
			})
			.addCase(fetchProduct.rejected, (state, action) => {
				state.error = action.payload
				state.loading = false
			})
			.addCase(fetchSetLike.fulfilled, (state, action) => {
				state.data = action.payload
				state.loading = false
			})
			.addCase(fetchSetLike.pending, (state) => {
				state.loading = true
				state.error = null
			})
			.addCase(fetchSetLike.rejected, (state, action) => {
				state.error = action.payload
				state.loading = false
			})
			.addCase(fetchSetDislike.fulfilled, (state, action) => {
				state.data = action.payload
				state.loading = false
			})
			.addCase(fetchSetDislike.pending, (state) => {
				state.loading = true
				state.error = null
			})
			.addCase(fetchSetDislike.rejected, (state, action) => {
				state.error = action.payload
				state.loading = false
			})
			.addCase(fetchAddReview.fulfilled, (state, action) => {
				state.data = action.payload
				state.loading = false
			})
			.addCase(fetchAddReview.pending, (state) => {
				state.loading = true
				state.error = null
			})
			.addCase(fetchAddReview.rejected, (state, action) => {
				state.error = action.payload
				state.loading = false
			})
	},
})
